#include "CRender.h"
#include "CDirectWrite.h"
#include "CCamera.h"


CRender::CRender()
{

}


CRender::~CRender()
{

}


CRender* CRender::GetInstance()
{
	static CRender render;
	return &render;
}


//bool CRender::InitNoneDevice(HWND hWnd)
//{
//	static const WCHAR msc_fontName[] = L"Verdana";
//	static const FLOAT msc_fontSize = 50;
//	ID2D1GeometrySink *pSink = NULL;
//	HRESULT hr;
//
//	// Create D2D factory
//	hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &m_pD2DFactory);
//	if (SUCCEEDED(hr))
//	{
//		// Create a WIC factory
//		hr = CoCreateInstance(
//			CLSID_WICImagingFactory,
//			NULL,
//			CLSCTX_INPROC_SERVER,
//			IID_IWICImagingFactory,
//			reinterpret_cast<void **>(&m_pWICFactory)
//			);
//	}
//	if (SUCCEEDED(hr))
//	{
//		// Create DWrite factory
//		hr = DWriteCreateFactory(
//			DWRITE_FACTORY_TYPE_SHARED,
//			__uuidof(m_pDWriteFactory),
//			reinterpret_cast<IUnknown **>(&m_pDWriteFactory)
//			);
//	}
//	if (SUCCEEDED(hr))
//	{
//		// Create DWrite text format object
//		hr = m_pDWriteFactory->CreateTextFormat(
//			msc_fontName,
//			NULL,
//			DWRITE_FONT_WEIGHT_NORMAL,
//			DWRITE_FONT_STYLE_NORMAL,
//			DWRITE_FONT_STRETCH_NORMAL,
//			msc_fontSize,
//			L"", //locale
//			&m_pTextFormat
//			);
//	}
//	if (SUCCEEDED(hr))
//	{
//		// Center the text both horizontally and vertically.
//		m_pTextFormat->SetTextAlignment(DWRITE_TEXT_ALIGNMENT_CENTER);
//		m_pTextFormat->SetParagraphAlignment(DWRITE_PARAGRAPH_ALIGNMENT_CENTER);
//
//		// Create the path geometry.
//		hr = m_pD2DFactory->CreatePathGeometry(&m_pPathGeometry);
//	}
//	if (SUCCEEDED(hr))
//	{
//		// Write to the path geometry using the geometry sink. We are going to create an
//		// hour glass.
//		hr = m_pPathGeometry->Open(&pSink);
//	}
//	if (SUCCEEDED(hr))
//	{
//		pSink->SetFillMode(D2D1_FILL_MODE_ALTERNATE);
//
//		pSink->BeginFigure(
//			D2D1::Point2F(0, 0),
//			D2D1_FIGURE_BEGIN_FILLED
//			);
//
//		pSink->AddLine(D2D1::Point2F(200, 0));
//
//		pSink->AddBezier(
//			D2D1::BezierSegment(
//			D2D1::Point2F(150, 50),
//			D2D1::Point2F(150, 150),
//			D2D1::Point2F(200, 200))
//			);
//
//		pSink->AddLine(D2D1::Point2F(0, 200));
//
//		pSink->AddBezier(
//			D2D1::BezierSegment(
//			D2D1::Point2F(50, 150),
//			D2D1::Point2F(50, 50),
//			D2D1::Point2F(0, 0))
//			);
//
//		pSink->EndFigure(D2D1_FIGURE_END_CLOSED);
//
//		hr = pSink->Close();
//	}
//
//	SafeRelease(&pSink);
//
//	return true;
//}
//

bool CRender::InitDevice(HWND hWnd)
{


	HRESULT hr = S_OK;

	RECT rc;
	GetClientRect( hWnd, &rc );
	UINT width = rc.right - rc.left;
	UINT height = rc.bottom - rc.top;

	UINT createDeviceFlags = 0;
#ifdef _DEBUG
	createDeviceFlags |= D3D10_CREATE_DEVICE_DEBUG;
#endif

	D3D10_DRIVER_TYPE driverTypes[] =
	{
		D3D10_DRIVER_TYPE_HARDWARE,
		D3D10_DRIVER_TYPE_REFERENCE,
	};
	UINT numDriverTypes = sizeof( driverTypes ) / sizeof( driverTypes[0] );

	DXGI_SWAP_CHAIN_DESC sd;
	ZeroMemory( &sd, sizeof( sd ) );
	sd.BufferCount = 1;
	sd.BufferDesc.Width = width;
	sd.BufferDesc.Height = height;
	sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
	sd.BufferDesc.RefreshRate.Numerator = 60;
	sd.BufferDesc.RefreshRate.Denominator = 1;
	sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
	sd.OutputWindow = hWnd;
	sd.SampleDesc.Count = 1;
	sd.SampleDesc.Quality = 0;
	sd.Windowed = TRUE;

	for( UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; driverTypeIndex++ )
	{
		m_DriverType = driverTypes[driverTypeIndex];
		hr = D3D10CreateDeviceAndSwapChain( NULL, m_DriverType, NULL, createDeviceFlags,
			D3D10_SDK_VERSION, &sd, &m_pSwapChain, &m_pD3DDevice );
		if( SUCCEEDED( hr ) )
			break;
	}
	if( FAILED( hr ) )
		return false;


	// Create a render target view
	ID3D10Texture2D* pBuffer;
	hr = m_pSwapChain->GetBuffer( 0, __uuidof( ID3D10Texture2D ), ( LPVOID* )&pBuffer );
	if( FAILED( hr ) )
		return false;

	hr = m_pD3DDevice->CreateRenderTargetView( pBuffer, NULL, &m_pRenderTargetView );
	pBuffer->Release();
	if( FAILED( hr ) )
		return false;

	m_pD3DDevice->OMSetRenderTargets( 1, &m_pRenderTargetView, NULL );


	// Setup the viewport
	D3D10_VIEWPORT vp;
	vp.Width = width;
	vp.Height = height;
	vp.MinDepth = 0.0f;
	vp.MaxDepth = 1.0f;
	vp.TopLeftX = 0;
	vp.TopLeftY = 0;
	m_pD3DDevice->RSSetViewports( 1, &vp );



	// Create the effect
	DWORD dwShaderFlags = D3D10_SHADER_ENABLE_STRICTNESS;
#if defined( DEBUG ) || defined( _DEBUG )
	// Set the D3D10_SHADER_DEBUG flag to embed debug information in the shaders.
	// Setting this flag improves the shader debugging experience, but still allows 
	// the shaders to be optimized and to run exactly the way they will run in 
	// the release configuration of this program.
	dwShaderFlags |= D3D10_SHADER_DEBUG;
#endif
	hr = D3DX10CreateEffectFromFile( "Resource/Shaders/Tutorial04.fx", NULL, NULL, "fx_4_0", dwShaderFlags, 0,
		m_pD3DDevice, NULL, NULL, &m_pEffect, NULL, NULL );
	if( FAILED( hr ) )
	{
		MessageBox( NULL,
			"The FX file cannot be located.  Please run this executable from the directory that contains the FX file.", "Error", MB_OK );
		return false;
	}

	// Obtain the technique
	m_pTechnique = m_pEffect->GetTechniqueByName( "Render" );

	// Obtain the variables
	g_pWorldVariable = m_pEffect->GetVariableByName( "World" )->AsMatrix();
	g_pViewVariable = m_pEffect->GetVariableByName( "View" )->AsMatrix();
	g_pProjectionVariable = m_pEffect->GetVariableByName( "Projection" )->AsMatrix();


	// Define the input layout
	D3D10_INPUT_ELEMENT_DESC layout[] =
	{
		{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0 },
		{ "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D10_INPUT_PER_VERTEX_DATA, 0 },
	};
	UINT numElements = sizeof( layout ) / sizeof( layout[0] );


	SimpleBuffer simBuff;

	// Create the input layout
	D3D10_PASS_DESC PassDesc;
	m_pTechnique->GetPassByIndex( 0 )->GetDesc( &PassDesc );
	hr = m_pD3DDevice->CreateInputLayout( layout, numElements, PassDesc.pIAInputSignature,
		PassDesc.IAInputSignatureSize, &simBuff.m_pVertexLayout );
	if( FAILED( hr ) )
		return false;


	// Create vertex buffer
	SimpleVertex vertices[] =
	{
		{ D3DXVECTOR3( -1.0f, 1.0f, -1.0f ), D3DXVECTOR4( 0.0f, 0.0f, 1.0f, 1.0f ) },
		{ D3DXVECTOR3( 1.0f, 1.0f, -1.0f ), D3DXVECTOR4( 0.0f, 1.0f, 0.0f, 1.0f ) },
		{ D3DXVECTOR3( 1.0f, 1.0f, 1.0f ), D3DXVECTOR4( 0.0f, 1.0f, 1.0f, 1.0f ) },
		{ D3DXVECTOR3( -1.0f, 1.0f, 1.0f ), D3DXVECTOR4( 1.0f, 0.0f, 0.0f, 1.0f ) },
		{ D3DXVECTOR3( -1.0f, -1.0f, -1.0f ), D3DXVECTOR4( 1.0f, 0.0f, 1.0f, 1.0f ) },
		{ D3DXVECTOR3( 1.0f, -1.0f, -1.0f ), D3DXVECTOR4( 1.0f, 1.0f, 0.0f, 1.0f ) },
		{ D3DXVECTOR3( 1.0f, -1.0f, 1.0f ), D3DXVECTOR4( 1.0f, 1.0f, 1.0f, 1.0f ) },
		{ D3DXVECTOR3( -1.0f, -1.0f, 1.0f ), D3DXVECTOR4( 0.0f, 0.0f, 0.0f, 1.0f ) },
	};


	D3D10_BUFFER_DESC bd;
	bd.Usage = D3D10_USAGE_DEFAULT;
	bd.ByteWidth = sizeof( SimpleVertex ) * 8;
	bd.BindFlags = D3D10_BIND_VERTEX_BUFFER;
	bd.CPUAccessFlags = 0;
	bd.MiscFlags = 0;
	D3D10_SUBRESOURCE_DATA InitData;
	InitData.pSysMem = vertices;
	hr = m_pD3DDevice->CreateBuffer( &bd, &InitData, &simBuff.m_pVertexBuffer );
	if( FAILED( hr ) )
		return false;



	// Create index buffer
	DWORD indices[] =
	{
		3,1,0,
		2,1,3,

		0,5,4,
		1,5,0,

		3,4,7,
		0,4,3,

		1,6,5,
		2,6,1,

		2,7,6,
		3,7,2,

		6,4,5,
		7,4,6,
	};
	bd.Usage = D3D10_USAGE_DEFAULT;
	bd.ByteWidth = sizeof( DWORD ) * 36;        // 36 vertices needed for 12 triangles in a triangle list
	bd.BindFlags = D3D10_BIND_INDEX_BUFFER;
	bd.CPUAccessFlags = 0;
	bd.MiscFlags = 0;
	InitData.pSysMem = indices;
	hr = m_pD3DDevice->CreateBuffer( &bd, &InitData, &simBuff.m_pIndexBuffer );
	if( FAILED( hr ) )
		return false;


	m_pSimpleBuffers.push_back(simBuff);


	//Camera stuff that shouldn't be here
	// Initialize the world matrix
	D3DXMatrixIdentity( &g_World );

	// Initialize the view matrix
	/*D3DXVECTOR3 Eye( 0.0f, 1.0f, -5.0f );
	D3DXVECTOR3 At( 0.0f, 1.0f, 0.0f );
	D3DXVECTOR3 Up( 0.0f, 1.0f, 0.0f );
	D3DXMatrixLookAtLH( &g_View, &Eye, &At, &Up );*/

	// Initialize the projection matrix
	//D3DXMatrixPerspectiveFovLH( &g_Projection, ( float )D3DX_PI * 0.5f, width / ( FLOAT )height, 0.01f, 100.0f );


	D3D10_VIEWPORT viewPort;
	viewPort.Width = width;
	viewPort.Height = height;
	viewPort.MinDepth = 0.0f;
	viewPort.MaxDepth = 1.0f;
	viewPort.TopLeftX = 0;
	viewPort.TopLeftY = 0;

	//m_pD3DDevice->RSSetViewports(1, &viewPort);
	D3DXMatrixOrthoOffCenterLH(&g_2DProjection, (float)viewPort.TopLeftX, (float)viewPort.Width, (float)viewPort.TopLeftY, (float)viewPort.Height, 0.1f, 10);




	// Set primitive topology
	m_pD3DDevice->IASetPrimitiveTopology( D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST );

	//srcTexture = LoadTexture2DFromFile("Resource/Images/test2.jpg");

	//if(srcTexture == NULL)
	//{
	//	MessageBox( NULL,
	//		"Background can't be found.", "Error", MB_OK );
	//	return false;
	//}


	D3DX10CreateSprite(m_pD3DDevice, 0, &m_pSpriteManager);

	D3D10_BLEND_DESC StateDesc;
	ZeroMemory(&StateDesc, sizeof(D3D10_BLEND_DESC));
	StateDesc.AlphaToCoverageEnable = FALSE;
	StateDesc.BlendEnable[0] = TRUE;
	StateDesc.SrcBlend = D3D10_BLEND_SRC_ALPHA;
	StateDesc.DestBlend = D3D10_BLEND_INV_SRC_ALPHA;
	StateDesc.BlendOp = D3D10_BLEND_OP_ADD;
	StateDesc.SrcBlendAlpha = D3D10_BLEND_ZERO;
	StateDesc.DestBlendAlpha = D3D10_BLEND_ZERO;
	StateDesc.BlendOpAlpha = D3D10_BLEND_OP_ADD;
	StateDesc.RenderTargetWriteMask[0] = D3D10_COLOR_WRITE_ENABLE_ALL;
	m_pD3DDevice->CreateBlendState(&StateDesc, &pBlendState10);
	
	return true;
}


bool CRender::Shutdown()
{
	if(m_pD3DDevice)
		m_pD3DDevice->ClearState();

	while(!m_pSimpleBuffers.empty())
	{
		if(m_pSimpleBuffers.back().m_pVertexBuffer)
			m_pSimpleBuffers.back().m_pVertexBuffer->Release();
		if(m_pSimpleBuffers.back().m_pVertexLayout)
			m_pSimpleBuffers.back().m_pVertexLayout->Release();
		if(m_pSimpleBuffers.back().m_pIndexBuffer)
			m_pSimpleBuffers.back().m_pIndexBuffer->Release();

		m_pSimpleBuffers.pop_back();
	}

	if(m_pSpriteManager)
	{
		m_pSpriteManager->Release();
	}

	if(m_pEffect)
		m_pEffect->Release();
	if(m_pRenderTargetView)
		m_pRenderTargetView->Release();
	if(m_pSwapChain)
		m_pSwapChain->Release();
	if(m_pD3DDevice)
		m_pD3DDevice->Release();
	

	return true;
}


void CRender::ClearBackBuffer()
{
	float ClearColor[4] = { 0.0f, 0.70f, 0.80f, 1.0f }; //red,green,blue,alpha
	m_pD3DDevice->ClearRenderTargetView(m_pRenderTargetView, ClearColor);
}


void CRender::PresentBackBuffer()
{
	m_pSwapChain->Present(0, 0);
}


HRESULT CRender::CompileShaderFromFile(char* szFileName, LPCSTR szEntryPoint, LPCSTR szShaderModel, ID3DBlob** ppBlobOut)
{
	HRESULT hr = S_OK;

	DWORD dwShaderFlags = D3DCOMPILE_ENABLE_STRICTNESS;
#if defined(DEBUG) || defined(_DEBUG)
	// Set the D3DCOMPILE_DEBUG flag to embed debug information in the shaders.
	// Setting this flag improves the shader debugging experience, but still allows 
	// the shaders to be optimized and to run exactly the way they will run in 
	// the release configuration of this program.
	dwShaderFlags |= D3DCOMPILE_DEBUG;
#endif

	ID3DBlob* pErrorBlob;
	hr = D3DX10CompileFromFile(szFileName, NULL, NULL, szEntryPoint, szShaderModel, 
		dwShaderFlags, 0, NULL, ppBlobOut, &pErrorBlob, NULL);
	if(FAILED(hr))
	{
		if(pErrorBlob != NULL)
			OutputDebugStringA((char*)pErrorBlob->GetBufferPointer());
		if(pErrorBlob) 
			pErrorBlob->Release();
		return hr;
	}
	if(pErrorBlob) 
		pErrorBlob->Release();

	return S_OK;
}


void CRender::Render()
{

	//Render2D();


	static float t = 0.0f;
	if( m_DriverType == D3D10_DRIVER_TYPE_REFERENCE )
	{
		t += ( float )D3DX_PI * 0.0125f;
	}
	else
	{
		static DWORD dwTimeStart = 0;
		DWORD dwTimeCur = GetTickCount();
		if( dwTimeStart == 0 )
			dwTimeStart = dwTimeCur;
		t = ( dwTimeCur - dwTimeStart ) / 1000.0f;
	}

	//
	// Animate the cube
	//
	D3DXMatrixRotationY( &g_World, t );

	//
	// Update variables
	//

	g_pWorldVariable->SetMatrix( ( float* )&g_World );
	g_pViewVariable->SetMatrix( ( float* )CCamera::GetInstance()->GetViewMatrix() );
	g_pProjectionVariable->SetMatrix( ( float* )CCamera::GetInstance()->GetProjectionMatrix() );


	// Set the input layout
	m_pD3DDevice->IASetInputLayout( m_pSimpleBuffers[0].m_pVertexLayout );
	m_pD3DDevice->IASetIndexBuffer( m_pSimpleBuffers[0].m_pIndexBuffer, DXGI_FORMAT_R32_UINT, 0 );

	// Set vertex buffer
	UINT stride = sizeof( SimpleVertex );
	UINT offset = 0;
	m_pD3DDevice->IASetVertexBuffers( 0, 1, &m_pSimpleBuffers[0].m_pVertexBuffer, &stride, &offset );

	// Set primitive topology
	m_pD3DDevice->IASetPrimitiveTopology( D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST );

	// Render a triangle
	D3D10_TECHNIQUE_DESC techDesc;
	m_pTechnique->GetDesc( &techDesc );
	for( UINT p = 0; p < techDesc.Passes; ++p )
	{
		m_pTechnique->GetPassByIndex( p )->Apply( 0 );
		m_pD3DDevice->DrawIndexed( 36, 0, 0 );
	}
}


void CRender::Render2D()
{

	//FLOAT OriginalBlendFactor[4];
	//UINT  OriginalSampleMask = 0;

	//// Save the current blend state
	//m_pD3DDevice->OMGetBlendState(&pOriginalBlendState10, OriginalBlendFactor, &OriginalSampleMask);

	//HRESULT hr = m_pSpriteManager->SetProjectionTransform(&g_2DProjection);

	//m_pSpriteManager->Begin(D3DX10_SPRITE_SORT_TEXTURE);

	//m_pSpriteManager->DrawSpritesBuffered(srcTexture, 1);

	//// Set the blend state for alpha drawing
	//if(pBlendState10)
	//{
	//	FLOAT NewBlendFactor[4] = {0,0,0,0};
	//	m_pD3DDevice->OMSetBlendState(pBlendState10, NewBlendFactor, 0xffffffff);
	//}

	//// Finish up and send the sprites to the hardware
	//m_pSpriteManager->Flush();
	//m_pSpriteManager->End();

	//// Restore the previous blend state
	//m_pD3DDevice->OMSetBlendState(pOriginalBlendState10, OriginalBlendFactor, OriginalSampleMask);

	//ID3D10Texture2D* pBackBuffer;
	//HRESULT hr = m_pSwapChain->GetBuffer(0, __uuidof(ID3D10Texture2D), (LPVOID*)&pBackBuffer);
	//if(FAILED(hr))
	//{
	//	return;
	//}

	//// fill a D3D10_TEXTURE2D_DESC with the texture details
	//D3D10_TEXTURE2D_DESC desc;
	//srcTexture->GetDesc(&desc);

	//// create the source region using the width and height from the 
	//// D3D10_TEXTURE2D_DESC structure
	//D3D10_BOX sourceRegion;
	//sourceRegion.left = 0;
	//sourceRegion.right = 1024;
	//sourceRegion.top = 0;
	//sourceRegion.bottom = 768;
	//sourceRegion.front = 0;
	//sourceRegion.back = 1;

	//m_pD3DDevice->CopySubresourceRegion(pBackBuffer, 0, 0, 0, 0, srcTexture, 0, &sourceRegion);
}


SSprite* CRender::LoadTexture2DFromFile(std::string fileName)
{
	ID3D10Texture2D* texture = NULL;
	ID3D10Resource* pRes = NULL;

	HRESULT hr = D3DX10CreateTextureFromFile(m_pD3DDevice, fileName.c_str(), NULL, NULL, &pRes, NULL);
	if(FAILED(hr))
	{
		return NULL;
	}

	pRes->QueryInterface(__uuidof(ID3D10Texture2D), (LPVOID*)&texture);
	pRes->Release();

	ID3D10ShaderResourceView *gSpriteTextureRV = NULL;

	GetResourceViewFromTexture(texture, &gSpriteTextureRV);

	SSprite* newSprite = new SSprite();

	D3DX10_SPRITE* pNewSprite = new D3DX10_SPRITE();
	pNewSprite->pTexture = gSpriteTextureRV;
	pNewSprite->TextureIndex = 0;
	pNewSprite->TexCoord.x = 0;
	pNewSprite->TexCoord.y = 0;
	pNewSprite->TexSize.x = 1;
	pNewSprite->TexSize.y = 1;
	pNewSprite->ColorModulate = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);

	newSprite->m_pSprite = pNewSprite;

	D3D10_TEXTURE2D_DESC dsc;
	texture->GetDesc(&dsc);

	newSprite->m_Width = dsc.Width;
	newSprite->m_Height = dsc.Height;

	//D3DXMATRIX scale;
	//D3DXMATRIX mat;
	//D3DXMatrixIdentity(&mat);

	//D3DXMatrixScaling(&scale, 512.0f, 512.0f, 1.0f);
	//D3DXMatrixTranslation(&mat, 256.0f + 50, 768.0f - (256.0f) - 50, 0.1f);

	//D3DXMATRIX idn;
	//D3DXMatrixIdentity(&idn);
	////pNewSprite->matWorld = idn;
	//pNewSprite->matWorld = scale * mat;


	texture->Release();
	return newSprite;
}


void CRender::GetResourceViewFromTexture(ID3D10Texture2D* texture, ID3D10ShaderResourceView **resourceView)
{
	if (texture != NULL)
	{
		// Get the texture details
		D3D10_TEXTURE2D_DESC desc;
		texture->GetDesc(&desc);

		// Create a shader resource view of the texture
		D3D10_SHADER_RESOURCE_VIEW_DESC SRVDesc;
		ZeroMemory(&SRVDesc, sizeof(SRVDesc));
		SRVDesc.Format = desc.Format;
		SRVDesc.ViewDimension = D3D10_SRV_DIMENSION_TEXTURE2D;
		SRVDesc.Texture2D.MipLevels = desc.MipLevels;

		m_pD3DDevice->CreateShaderResourceView(texture, &SRVDesc, resourceView);
	}
}


//take this shit out
void CRender::Render2D(D3DX10_SPRITE* texture)
{

	FLOAT OriginalBlendFactor[4];
	UINT  OriginalSampleMask = 0;

	// Save the current blend state
	m_pD3DDevice->OMGetBlendState(&pOriginalBlendState10, OriginalBlendFactor, &OriginalSampleMask);

	HRESULT hr = m_pSpriteManager->SetProjectionTransform(&g_2DProjection);

	m_pSpriteManager->Begin(D3DX10_SPRITE_SORT_TEXTURE);

	m_pSpriteManager->DrawSpritesBuffered(texture, 1);

	// Set the blend state for alpha drawing
	if(pBlendState10)
	{
		FLOAT NewBlendFactor[4] = {0,0,0,0};
		m_pD3DDevice->OMSetBlendState(pBlendState10, NewBlendFactor, 0xffffffff);
	}

	// Finish up and send the sprites to the hardware
	m_pSpriteManager->Flush();
	m_pSpriteManager->End();


	m_pD3DDevice->OMSetBlendState(pOriginalBlendState10, OriginalBlendFactor, OriginalSampleMask);


	//m_pSpriteManager->Begin(D3DX10_SPRITE_SORT_TEXTURE);

	//ID3D10Texture2D* pBackBuffer;
	//HRESULT hr = m_pSwapChain->GetBuffer(0, __uuidof(ID3D10Texture2D), (LPVOID*)&pBackBuffer);
	//if(FAILED(hr))
	//{
	//	return;
	//}

	//// fill a D3D10_TEXTURE2D_DESC with the texture details
	//D3D10_TEXTURE2D_DESC desc;
	//texture->GetDesc(&desc);

	//// create the source region using the width and height from the 
	//// D3D10_TEXTURE2D_DESC structure
	//D3D10_BOX sourceRegion;
	//sourceRegion.left = 0;
	//sourceRegion.right = desc.Width;
	//sourceRegion.top = 0;
	//sourceRegion.bottom = desc.Height;
	//sourceRegion.front = 0;
	//sourceRegion.back = 1;


	//m_pD3DDevice->CopySubresourceRegion(pBackBuffer, 0, x, y, 0, texture, 0, &sourceRegion);

	//m_pSpriteManager->End();
}